/*
 * Tests of IEEE 754 single-precision addition and subtraction
 *
 * Copyright (c) 1999-2025, Arm Limited.
 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
 */

#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

enum operation
{
  ADD,
  SUB,
};

struct test
{
  enum operation op;
  uint32_t in1, in2, out;
};

static const struct test tests[] = {
  // Tests that don't depend on Arm-specific NaN policy
  { ADD, 0x00000000, 0x00000000, 0x00000000 },
  { ADD, 0x00000000, 0x007fffff, 0x007fffff },
  { ADD, 0x00000000, 0x3f800000, 0x3f800000 },
  { ADD, 0x00000000, 0x7f000000, 0x7f000000 },
  { ADD, 0x00000000, 0x7f800000, 0x7f800000 },
  { ADD, 0x00000000, 0x80000000, 0x00000000 },
  { ADD, 0x00000000, 0x807fffff, 0x807fffff },
  { ADD, 0x00000000, 0x80800000, 0x80800000 },
  { ADD, 0x00000000, 0xff800000, 0xff800000 },
  { ADD, 0x00000001, 0x00000001, 0x00000002 },
  { ADD, 0x00000001, 0x3f7fffff, 0x3f7fffff },
  { ADD, 0x00000001, 0x3f800000, 0x3f800000 },
  { ADD, 0x00000001, 0x3ffffffe, 0x3ffffffe },
  { ADD, 0x00000001, 0x3fffffff, 0x3fffffff },
  { ADD, 0x00000001, 0x7effffff, 0x7effffff },
  { ADD, 0x00000001, 0x7f000000, 0x7f000000 },
  { ADD, 0x00000001, 0x7f7ffffe, 0x7f7ffffe },
  { ADD, 0x00000001, 0x7f7fffff, 0x7f7fffff },
  { ADD, 0x00000001, 0x80000001, 0x00000000 },
  { ADD, 0x00000002, 0x80000001, 0x00000001 },
  { ADD, 0x00000003, 0x00000000, 0x00000003 },
  { ADD, 0x00000003, 0x7f800000, 0x7f800000 },
  { ADD, 0x00000003, 0x80000000, 0x00000003 },
  { ADD, 0x00000003, 0x80000002, 0x00000001 },
  { ADD, 0x00000003, 0xc0a00000, 0xc0a00000 },
  { ADD, 0x00000003, 0xff000000, 0xff000000 },
  { ADD, 0x00000003, 0xff800000, 0xff800000 },
  { ADD, 0x00000004, 0x00000004, 0x00000008 },
  { ADD, 0x007ffffc, 0x807ffffc, 0x00000000 },
  { ADD, 0x007ffffd, 0x807ffffe, 0x80000001 },
  { ADD, 0x007fffff, 0x007fffff, 0x00fffffe },
  { ADD, 0x007fffff, 0x807ffffe, 0x00000001 },
  { ADD, 0x007fffff, 0x80800000, 0x80000001 },
  { ADD, 0x00800000, 0x00000000, 0x00800000 },
  { ADD, 0x00800000, 0x00800000, 0x01000000 },
  { ADD, 0x00800000, 0x80800000, 0x00000000 },
  { ADD, 0x00800001, 0x80800000, 0x00000001 },
  { ADD, 0x00800001, 0x80800002, 0x80000001 },
  { ADD, 0x00ffffff, 0x81000000, 0x80000001 },
  { ADD, 0x00ffffff, 0x81000002, 0x80000005 },
  { ADD, 0x00ffffff, 0x81000004, 0x80000009 },
  { ADD, 0x01000000, 0x80ffffff, 0x00000001 },
  { ADD, 0x01000001, 0x80800001, 0x00800001 },
  { ADD, 0x01000001, 0x80ffffff, 0x00000003 },
  { ADD, 0x01000002, 0x80800001, 0x00800003 },
  { ADD, 0x017fffff, 0x81800000, 0x80000002 },
  { ADD, 0x01800000, 0x817fffff, 0x00000002 },
  { ADD, 0x01800001, 0x817fffff, 0x00000006 },
  { ADD, 0x01800002, 0x81000003, 0x01000001 },
  { ADD, 0x3f7fffff, 0x80000001, 0x3f7fffff },
  { ADD, 0x3f800000, 0x3f800000, 0x40000000 },
  { ADD, 0x3f800000, 0x3f800003, 0x40000002 },
  { ADD, 0x3f800000, 0x40000000, 0x40400000 },
  { ADD, 0x3f800000, 0x40e00000, 0x41000000 },
  { ADD, 0x3f800000, 0x80000000, 0x3f800000 },
  { ADD, 0x3f800000, 0xbf800000, 0x00000000 },
  { ADD, 0x3f800001, 0x3f800000, 0x40000000 },
  { ADD, 0x3f800001, 0xbf800000, 0x34000000 },
  { ADD, 0x3f800001, 0xbf800002, 0xb4000000 },
  { ADD, 0x3ffffffc, 0xbffffffd, 0xb4000000 },
  { ADD, 0x3fffffff, 0xc0000000, 0xb4000000 },
  { ADD, 0x40000000, 0x34000000, 0x40000000 },
  { ADD, 0x40000000, 0x3f800000, 0x40400000 },
  { ADD, 0x40000000, 0x40000000, 0x40800000 },
  { ADD, 0x40000000, 0x40000001, 0x40800000 },
  { ADD, 0x40000000, 0xbfffffff, 0x34000000 },
  { ADD, 0x40000000, 0xc0000000, 0x00000000 },
  { ADD, 0x40000000, 0xc0000001, 0xb4800000 },
  { ADD, 0x40000000, 0xc0a00000, 0xc0400000 },
  { ADD, 0x40000001, 0x34000000, 0x40000002 },
  { ADD, 0x40000001, 0x40000002, 0x40800002 },
  { ADD, 0x40000001, 0xbf800001, 0x3f800001 },
  { ADD, 0x40000002, 0xbf800001, 0x3f800003 },
  { ADD, 0x40000002, 0xbf800003, 0x3f800001 },
  { ADD, 0x40000004, 0xc0000003, 0x34800000 },
  { ADD, 0x40400000, 0x40400000, 0x40c00000 },
  { ADD, 0x407fffff, 0x33ffffff, 0x407fffff },
  { ADD, 0x407fffff, 0x34000000, 0x40800000 },
  { ADD, 0x407fffff, 0xc07ffffe, 0x34800000 },
  { ADD, 0x407fffff, 0xc0800002, 0xb5a00000 },
  { ADD, 0x40800001, 0xc07fffff, 0x35400000 },
  { ADD, 0x40a00000, 0x00000000, 0x40a00000 },
  { ADD, 0x40a00000, 0x80000000, 0x40a00000 },
  { ADD, 0x40a00000, 0xbf800000, 0x40800000 },
  { ADD, 0x40a00000, 0xc0a00000, 0x00000000 },
  { ADD, 0x7d800001, 0xfd7fffff, 0x72400000 },
  { ADD, 0x7e7fffff, 0xfe7ffffe, 0x72800000 },
  { ADD, 0x7e7fffff, 0xfe800002, 0xf3a00000 },
  { ADD, 0x7e800000, 0x7e800000, 0x7f000000 },
  { ADD, 0x7e800000, 0xfe7fffff, 0x72800000 },
  { ADD, 0x7e800000, 0xfe800001, 0xf3000000 },
  { ADD, 0x7e800001, 0x7e800000, 0x7f000000 },
  { ADD, 0x7e800001, 0xff000001, 0xfe800001 },
  { ADD, 0x7e800002, 0xfe000003, 0x7e000001 },
  { ADD, 0x7e800004, 0xfe800003, 0x73000000 },
  { ADD, 0x7efffffe, 0x7efffffe, 0x7f7ffffe },
  { ADD, 0x7efffffe, 0x7effffff, 0x7f7ffffe },
  { ADD, 0x7effffff, 0x3f800000, 0x7effffff },
  { ADD, 0x7effffff, 0x7f000000, 0x7f800000 },
  { ADD, 0x7effffff, 0xbf800000, 0x7effffff },
  { ADD, 0x7effffff, 0xff000000, 0xf3000000 },
  { ADD, 0x7f000000, 0x3f800000, 0x7f000000 },
  { ADD, 0x7f000000, 0x7f000000, 0x7f800000 },
  { ADD, 0x7f000000, 0x7f800000, 0x7f800000 },
  { ADD, 0x7f000000, 0xbf800000, 0x7f000000 },
  { ADD, 0x7f000000, 0xff000000, 0x00000000 },
  { ADD, 0x7f000000, 0xff800000, 0xff800000 },
  { ADD, 0x7f000001, 0x7f000000, 0x7f800000 },
  { ADD, 0x7f000001, 0xff000000, 0x73800000 },
  { ADD, 0x7f000001, 0xff000002, 0xf3800000 },
  { ADD, 0x7f000002, 0xfe800001, 0x7e800003 },
  { ADD, 0x7f7ffffe, 0x3f800000, 0x7f7ffffe },
  { ADD, 0x7f7ffffe, 0x7f7ffffe, 0x7f800000 },
  { ADD, 0x7f7ffffe, 0x7f7fffff, 0x7f800000 },
  { ADD, 0x7f7ffffe, 0xbf800000, 0x7f7ffffe },
  { ADD, 0x7f7ffffe, 0xff7fffff, 0xf3800000 },
  { ADD, 0x7f7fffff, 0x3f800000, 0x7f7fffff },
  { ADD, 0x7f7fffff, 0x80000001, 0x7f7fffff },
  { ADD, 0x7f7fffff, 0xbf800000, 0x7f7fffff },
  { ADD, 0x7f7fffff, 0xff7fffff, 0x00000000 },
  { ADD, 0x7f800000, 0x00000000, 0x7f800000 },
  { ADD, 0x7f800000, 0x007fffff, 0x7f800000 },
  { ADD, 0x7f800000, 0x7f000000, 0x7f800000 },
  { ADD, 0x7f800000, 0x7f800000, 0x7f800000 },
  { ADD, 0x7f800000, 0x80000000, 0x7f800000 },
  { ADD, 0x7f800000, 0x807fffff, 0x7f800000 },
  { ADD, 0x7f800000, 0xff000000, 0x7f800000 },
  { ADD, 0x80000000, 0x00000000, 0x00000000 },
  { ADD, 0x80000000, 0x007fffff, 0x007fffff },
  { ADD, 0x80000000, 0x7f000000, 0x7f000000 },
  { ADD, 0x80000000, 0x7f800000, 0x7f800000 },
  { ADD, 0x80000000, 0x80000000, 0x80000000 },
  { ADD, 0x80000000, 0x807fffff, 0x807fffff },
  { ADD, 0x80000000, 0x80800000, 0x80800000 },
  { ADD, 0x80000000, 0xbf800000, 0xbf800000 },
  { ADD, 0x80000000, 0xff800000, 0xff800000 },
  { ADD, 0x80000001, 0x00000001, 0x00000000 },
  { ADD, 0x80000001, 0x80000001, 0x80000002 },
  { ADD, 0x80000001, 0xbf7fffff, 0xbf7fffff },
  { ADD, 0x80000001, 0xbf800000, 0xbf800000 },
  { ADD, 0x80000001, 0xbffffffe, 0xbffffffe },
  { ADD, 0x80000001, 0xbfffffff, 0xbfffffff },
  { ADD, 0x80000001, 0xfeffffff, 0xfeffffff },
  { ADD, 0x80000001, 0xff000000, 0xff000000 },
  { ADD, 0x80000001, 0xff7ffffe, 0xff7ffffe },
  { ADD, 0x80000001, 0xff7fffff, 0xff7fffff },
  { ADD, 0x80000002, 0x00000001, 0x80000001 },
  { ADD, 0x80000003, 0x00000000, 0x80000003 },
  { ADD, 0x80000003, 0x00000002, 0x80000001 },
  { ADD, 0x80000003, 0x40400000, 0x40400000 },
  { ADD, 0x80000003, 0x7f000000, 0x7f000000 },
  { ADD, 0x80000003, 0x7f800000, 0x7f800000 },
  { ADD, 0x80000003, 0x80000000, 0x80000003 },
  { ADD, 0x80000003, 0xff800000, 0xff800000 },
  { ADD, 0x80000004, 0x80000004, 0x80000008 },
  { ADD, 0x807ffffd, 0x007ffffe, 0x00000001 },
  { ADD, 0x807fffff, 0x007ffffe, 0x80000001 },
  { ADD, 0x807fffff, 0x007fffff, 0x00000000 },
  { ADD, 0x807fffff, 0x00800000, 0x00000001 },
  { ADD, 0x807fffff, 0x807fffff, 0x80fffffe },
  { ADD, 0x80800000, 0x00000000, 0x80800000 },
  { ADD, 0x80800000, 0x00800000, 0x00000000 },
  { ADD, 0x80800001, 0x00800000, 0x80000001 },
  { ADD, 0x80800001, 0x00800002, 0x00000001 },
  { ADD, 0x80ffffff, 0x01000000, 0x00000001 },
  { ADD, 0x80ffffff, 0x01000002, 0x00000005 },
  { ADD, 0x80ffffff, 0x01000004, 0x00000009 },
  { ADD, 0x81000000, 0x00ffffff, 0x80000001 },
  { ADD, 0x81000001, 0x00800001, 0x80800001 },
  { ADD, 0x81000001, 0x00ffffff, 0x80000003 },
  { ADD, 0x81000002, 0x00800001, 0x80800003 },
  { ADD, 0x817fffff, 0x01800000, 0x00000002 },
  { ADD, 0x81800000, 0x017fffff, 0x80000002 },
  { ADD, 0x81800001, 0x017fffff, 0x80000006 },
  { ADD, 0x81800002, 0x01000003, 0x81000001 },
  { ADD, 0xbf800000, 0x80000000, 0xbf800000 },
  { ADD, 0xbf800000, 0xbf800003, 0xc0000002 },
  { ADD, 0xbf800001, 0x3f800000, 0xb4000000 },
  { ADD, 0xbf800001, 0x3f800002, 0x34000000 },
  { ADD, 0xbf800001, 0xbf800000, 0xc0000000 },
  { ADD, 0xbffffffc, 0x3ffffffd, 0x34000000 },
  { ADD, 0xbfffffff, 0x00000001, 0xbfffffff },
  { ADD, 0xbfffffff, 0x40000000, 0x34000000 },
  { ADD, 0xc0000000, 0x3fffffff, 0xb4000000 },
  { ADD, 0xc0000000, 0x40000001, 0x34800000 },
  { ADD, 0xc0000000, 0xc0000001, 0xc0800000 },
  { ADD, 0xc0000001, 0x3f800001, 0xbf800001 },
  { ADD, 0xc0000001, 0xc0000002, 0xc0800002 },
  { ADD, 0xc0000002, 0x3f800001, 0xbf800003 },
  { ADD, 0xc0000002, 0x3f800003, 0xbf800001 },
  { ADD, 0xc0000004, 0x40000003, 0xb4800000 },
  { ADD, 0xc0400000, 0x40400000, 0x00000000 },
  { ADD, 0xc07fffff, 0x407ffffe, 0xb4800000 },
  { ADD, 0xc07fffff, 0x40800002, 0x35a00000 },
  { ADD, 0xc07fffff, 0xb3ffffff, 0xc07fffff },
  { ADD, 0xc07fffff, 0xb4000000, 0xc0800000 },
  { ADD, 0xc0800001, 0x407fffff, 0xb5400000 },
  { ADD, 0xfd800001, 0x7d7fffff, 0xf2400000 },
  { ADD, 0xfe7fffff, 0x7e7ffffe, 0xf2800000 },
  { ADD, 0xfe7fffff, 0x7e800002, 0x73a00000 },
  { ADD, 0xfe800000, 0x7e7fffff, 0xf2800000 },
  { ADD, 0xfe800000, 0x7e800001, 0x73000000 },
  { ADD, 0xfe800001, 0x7f000001, 0x7e800001 },
  { ADD, 0xfe800001, 0xfe800000, 0xff000000 },
  { ADD, 0xfe800002, 0x7e000003, 0xfe000001 },
  { ADD, 0xfe800004, 0x7e800003, 0xf3000000 },
  { ADD, 0xfefffffe, 0x7efffffe, 0x00000000 },
  { ADD, 0xfefffffe, 0xfefffffe, 0xff7ffffe },
  { ADD, 0xfefffffe, 0xfeffffff, 0xff7ffffe },
  { ADD, 0xfeffffff, 0x3f800000, 0xfeffffff },
  { ADD, 0xfeffffff, 0x7f000000, 0x73000000 },
  { ADD, 0xfeffffff, 0xbf800000, 0xfeffffff },
  { ADD, 0xfeffffff, 0xff000000, 0xff800000 },
  { ADD, 0xff000000, 0x00000000, 0xff000000 },
  { ADD, 0xff000000, 0x3f800000, 0xff000000 },
  { ADD, 0xff000000, 0x7f800000, 0x7f800000 },
  { ADD, 0xff000000, 0x80000000, 0xff000000 },
  { ADD, 0xff000000, 0xbf800000, 0xff000000 },
  { ADD, 0xff000000, 0xff000000, 0xff800000 },
  { ADD, 0xff000000, 0xff800000, 0xff800000 },
  { ADD, 0xff000001, 0x7f000000, 0xf3800000 },
  { ADD, 0xff000001, 0x7f000002, 0x73800000 },
  { ADD, 0xff000001, 0xff000000, 0xff800000 },
  { ADD, 0xff000002, 0x7e800001, 0xfe800003 },
  { ADD, 0xff7ffffe, 0x3f800000, 0xff7ffffe },
  { ADD, 0xff7ffffe, 0x7f7fffff, 0x73800000 },
  { ADD, 0xff7ffffe, 0xbf800000, 0xff7ffffe },
  { ADD, 0xff7ffffe, 0xff7ffffe, 0xff800000 },
  { ADD, 0xff7ffffe, 0xff7fffff, 0xff800000 },
  { ADD, 0xff7fffff, 0x00000001, 0xff7fffff },
  { ADD, 0xff7fffff, 0x3f800000, 0xff7fffff },
  { ADD, 0xff7fffff, 0xbf800000, 0xff7fffff },
  { ADD, 0xff800000, 0x00000000, 0xff800000 },
  { ADD, 0xff800000, 0x007fffff, 0xff800000 },
  { ADD, 0xff800000, 0x7f000000, 0xff800000 },
  { ADD, 0xff800000, 0x80000000, 0xff800000 },
  { ADD, 0xff800000, 0x807fffff, 0xff800000 },
  { ADD, 0xff800000, 0xff000000, 0xff800000 },
  { ADD, 0xff800000, 0xff800000, 0xff800000 },
  { ADD, 0x7f7fffff, 0x74ffffff, 0x7f800000 },
  { ADD, 0x3f7fffff, 0x34004000, 0x3f800001 },
  { ADD, 0x3f800001, 0x23800000, 0x3f800001 },
  { ADD, 0xbbebe66d, 0x3b267c1f, 0xbb98a85e },
  { ADD, 0x01f5b166, 0x81339a37, 0x019be44a },
  { SUB, 0x00000000, 0x00000000, 0x00000000 },
  { SUB, 0x00000000, 0x007fffff, 0x807fffff },
  { SUB, 0x00000000, 0x00800000, 0x80800000 },
  { SUB, 0x00000000, 0x7f800000, 0xff800000 },
  { SUB, 0x00000000, 0x80000000, 0x00000000 },
  { SUB, 0x00000000, 0x807fffff, 0x007fffff },
  { SUB, 0x00000000, 0xbf800000, 0x3f800000 },
  { SUB, 0x00000000, 0xff000000, 0x7f000000 },
  { SUB, 0x00000000, 0xff800000, 0x7f800000 },
  { SUB, 0x00000001, 0x00000001, 0x00000000 },
  { SUB, 0x00000001, 0x80000001, 0x00000002 },
  { SUB, 0x00000001, 0xbf7fffff, 0x3f7fffff },
  { SUB, 0x00000001, 0xbf800000, 0x3f800000 },
  { SUB, 0x00000001, 0xbffffffe, 0x3ffffffe },
  { SUB, 0x00000001, 0xbfffffff, 0x3fffffff },
  { SUB, 0x00000001, 0xfeffffff, 0x7effffff },
  { SUB, 0x00000001, 0xff000000, 0x7f000000 },
  { SUB, 0x00000001, 0xff7ffffe, 0x7f7ffffe },
  { SUB, 0x00000001, 0xff7fffff, 0x7f7fffff },
  { SUB, 0x00000002, 0x00000001, 0x00000001 },
  { SUB, 0x00000003, 0x00000000, 0x00000003 },
  { SUB, 0x00000003, 0x00000002, 0x00000001 },
  { SUB, 0x00000003, 0x40a00000, 0xc0a00000 },
  { SUB, 0x00000003, 0x7f000000, 0xff000000 },
  { SUB, 0x00000003, 0x7f800000, 0xff800000 },
  { SUB, 0x00000003, 0x80000000, 0x00000003 },
  { SUB, 0x00000003, 0xff800000, 0x7f800000 },
  { SUB, 0x00000004, 0x80000004, 0x00000008 },
  { SUB, 0x007ffffc, 0x007ffffc, 0x00000000 },
  { SUB, 0x007ffffd, 0x007ffffe, 0x80000001 },
  { SUB, 0x007fffff, 0x007ffffe, 0x00000001 },
  { SUB, 0x007fffff, 0x00800000, 0x80000001 },
  { SUB, 0x007fffff, 0x807fffff, 0x00fffffe },
  { SUB, 0x00800000, 0x00800000, 0x00000000 },
  { SUB, 0x00800000, 0x80000000, 0x00800000 },
  { SUB, 0x00800000, 0x80800000, 0x01000000 },
  { SUB, 0x00800001, 0x00800000, 0x00000001 },
  { SUB, 0x00800001, 0x00800002, 0x80000001 },
  { SUB, 0x00ffffff, 0x01000000, 0x80000001 },
  { SUB, 0x00ffffff, 0x01000002, 0x80000005 },
  { SUB, 0x00ffffff, 0x01000004, 0x80000009 },
  { SUB, 0x01000000, 0x00ffffff, 0x00000001 },
  { SUB, 0x01000001, 0x00800001, 0x00800001 },
  { SUB, 0x01000001, 0x00ffffff, 0x00000003 },
  { SUB, 0x01000002, 0x00800001, 0x00800003 },
  { SUB, 0x017fffff, 0x01800000, 0x80000002 },
  { SUB, 0x01800000, 0x017fffff, 0x00000002 },
  { SUB, 0x01800001, 0x017fffff, 0x00000006 },
  { SUB, 0x01800002, 0x01000003, 0x01000001 },
  { SUB, 0x3f7fffff, 0x00000001, 0x3f7fffff },
  { SUB, 0x3f800000, 0x00000000, 0x3f800000 },
  { SUB, 0x3f800000, 0x3f800000, 0x00000000 },
  { SUB, 0x3f800000, 0xbf800000, 0x40000000 },
  { SUB, 0x3f800000, 0xbf800003, 0x40000002 },
  { SUB, 0x3f800000, 0xc0000000, 0x40400000 },
  { SUB, 0x3f800000, 0xc0e00000, 0x41000000 },
  { SUB, 0x3f800001, 0x3f800000, 0x34000000 },
  { SUB, 0x3f800001, 0x3f800002, 0xb4000000 },
  { SUB, 0x3f800001, 0xbf800000, 0x40000000 },
  { SUB, 0x3ffffffc, 0x3ffffffd, 0xb4000000 },
  { SUB, 0x3fffffff, 0x40000000, 0xb4000000 },
  { SUB, 0x40000000, 0x3fffffff, 0x34000000 },
  { SUB, 0x40000000, 0x40000000, 0x00000000 },
  { SUB, 0x40000000, 0x40000001, 0xb4800000 },
  { SUB, 0x40000000, 0x40a00000, 0xc0400000 },
  { SUB, 0x40000000, 0xb4000000, 0x40000000 },
  { SUB, 0x40000000, 0xbf800000, 0x40400000 },
  { SUB, 0x40000000, 0xc0000000, 0x40800000 },
  { SUB, 0x40000000, 0xc0000001, 0x40800000 },
  { SUB, 0x40000001, 0x3f800001, 0x3f800001 },
  { SUB, 0x40000001, 0xb4000000, 0x40000002 },
  { SUB, 0x40000001, 0xc0000002, 0x40800002 },
  { SUB, 0x40000002, 0x3f800001, 0x3f800003 },
  { SUB, 0x40000002, 0x3f800003, 0x3f800001 },
  { SUB, 0x40000004, 0x40000003, 0x34800000 },
  { SUB, 0x40400000, 0xc0400000, 0x40c00000 },
  { SUB, 0x407fffff, 0x407ffffe, 0x34800000 },
  { SUB, 0x407fffff, 0x40800002, 0xb5a00000 },
  { SUB, 0x407fffff, 0xb3ffffff, 0x407fffff },
  { SUB, 0x407fffff, 0xb4000000, 0x40800000 },
  { SUB, 0x40800001, 0x407fffff, 0x35400000 },
  { SUB, 0x40a00000, 0x00000000, 0x40a00000 },
  { SUB, 0x40a00000, 0x3f800000, 0x40800000 },
  { SUB, 0x40a00000, 0x40a00000, 0x00000000 },
  { SUB, 0x40a00000, 0x80000000, 0x40a00000 },
  { SUB, 0x7d800001, 0x7d7fffff, 0x72400000 },
  { SUB, 0x7e7fffff, 0x7e7ffffe, 0x72800000 },
  { SUB, 0x7e7fffff, 0x7e800002, 0xf3a00000 },
  { SUB, 0x7e800000, 0x7e7fffff, 0x72800000 },
  { SUB, 0x7e800000, 0x7e800001, 0xf3000000 },
  { SUB, 0x7e800000, 0xfe800000, 0x7f000000 },
  { SUB, 0x7e800001, 0x7f000001, 0xfe800001 },
  { SUB, 0x7e800001, 0xfe800000, 0x7f000000 },
  { SUB, 0x7e800002, 0x7e000003, 0x7e000001 },
  { SUB, 0x7e800004, 0x7e800003, 0x73000000 },
  { SUB, 0x7efffffe, 0xfefffffe, 0x7f7ffffe },
  { SUB, 0x7efffffe, 0xfeffffff, 0x7f7ffffe },
  { SUB, 0x7effffff, 0x3f800000, 0x7effffff },
  { SUB, 0x7effffff, 0x7f000000, 0xf3000000 },
  { SUB, 0x7effffff, 0xbf800000, 0x7effffff },
  { SUB, 0x7effffff, 0xff000000, 0x7f800000 },
  { SUB, 0x7f000000, 0x3f800000, 0x7f000000 },
  { SUB, 0x7f000000, 0x7f000000, 0x00000000 },
  { SUB, 0x7f000000, 0x7f800000, 0xff800000 },
  { SUB, 0x7f000000, 0xbf800000, 0x7f000000 },
  { SUB, 0x7f000000, 0xff000000, 0x7f800000 },
  { SUB, 0x7f000000, 0xff800000, 0x7f800000 },
  { SUB, 0x7f000001, 0x7f000000, 0x73800000 },
  { SUB, 0x7f000001, 0x7f000002, 0xf3800000 },
  { SUB, 0x7f000001, 0xff000000, 0x7f800000 },
  { SUB, 0x7f000002, 0x7e800001, 0x7e800003 },
  { SUB, 0x7f7ffffe, 0x3f800000, 0x7f7ffffe },
  { SUB, 0x7f7ffffe, 0x7f7fffff, 0xf3800000 },
  { SUB, 0x7f7ffffe, 0xbf800000, 0x7f7ffffe },
  { SUB, 0x7f7ffffe, 0xff7ffffe, 0x7f800000 },
  { SUB, 0x7f7ffffe, 0xff7fffff, 0x7f800000 },
  { SUB, 0x7f7fffff, 0x00000001, 0x7f7fffff },
  { SUB, 0x7f7fffff, 0x3f800000, 0x7f7fffff },
  { SUB, 0x7f7fffff, 0x7f7fffff, 0x00000000 },
  { SUB, 0x7f7fffff, 0xbf800000, 0x7f7fffff },
  { SUB, 0x7f800000, 0x00000000, 0x7f800000 },
  { SUB, 0x7f800000, 0x007fffff, 0x7f800000 },
  { SUB, 0x7f800000, 0x7f000000, 0x7f800000 },
  { SUB, 0x7f800000, 0x80000000, 0x7f800000 },
  { SUB, 0x7f800000, 0x807fffff, 0x7f800000 },
  { SUB, 0x7f800000, 0xff000000, 0x7f800000 },
  { SUB, 0x7f800000, 0xff800000, 0x7f800000 },
  { SUB, 0x80000000, 0x00000000, 0x80000000 },
  { SUB, 0x80000000, 0x007fffff, 0x807fffff },
  { SUB, 0x80000000, 0x00800000, 0x80800000 },
  { SUB, 0x80000000, 0x3f800000, 0xbf800000 },
  { SUB, 0x80000000, 0x7f800000, 0xff800000 },
  { SUB, 0x80000000, 0x80000000, 0x00000000 },
  { SUB, 0x80000000, 0x807fffff, 0x007fffff },
  { SUB, 0x80000000, 0xff000000, 0x7f000000 },
  { SUB, 0x80000000, 0xff800000, 0x7f800000 },
  { SUB, 0x80000001, 0x00000001, 0x80000002 },
  { SUB, 0x80000001, 0x3f7fffff, 0xbf7fffff },
  { SUB, 0x80000001, 0x3f800000, 0xbf800000 },
  { SUB, 0x80000001, 0x3ffffffe, 0xbffffffe },
  { SUB, 0x80000001, 0x3fffffff, 0xbfffffff },
  { SUB, 0x80000001, 0x7effffff, 0xfeffffff },
  { SUB, 0x80000001, 0x7f000000, 0xff000000 },
  { SUB, 0x80000001, 0x7f7ffffe, 0xff7ffffe },
  { SUB, 0x80000001, 0x7f7fffff, 0xff7fffff },
  { SUB, 0x80000001, 0x80000001, 0x00000000 },
  { SUB, 0x80000002, 0x80000001, 0x80000001 },
  { SUB, 0x80000003, 0x00000000, 0x80000003 },
  { SUB, 0x80000003, 0x7f800000, 0xff800000 },
  { SUB, 0x80000003, 0x80000000, 0x80000003 },
  { SUB, 0x80000003, 0x80000002, 0x80000001 },
  { SUB, 0x80000003, 0xc0400000, 0x40400000 },
  { SUB, 0x80000003, 0xff000000, 0x7f000000 },
  { SUB, 0x80000003, 0xff800000, 0x7f800000 },
  { SUB, 0x80000004, 0x00000004, 0x80000008 },
  { SUB, 0x807ffffd, 0x807ffffe, 0x00000001 },
  { SUB, 0x807fffff, 0x007fffff, 0x80fffffe },
  { SUB, 0x807fffff, 0x807ffffe, 0x80000001 },
  { SUB, 0x807fffff, 0x807fffff, 0x00000000 },
  { SUB, 0x807fffff, 0x80800000, 0x00000001 },
  { SUB, 0x80800000, 0x80000000, 0x80800000 },
  { SUB, 0x80800000, 0x80800000, 0x00000000 },
  { SUB, 0x80800001, 0x80800000, 0x80000001 },
  { SUB, 0x80800001, 0x80800002, 0x00000001 },
  { SUB, 0x80ffffff, 0x81000000, 0x00000001 },
  { SUB, 0x80ffffff, 0x81000002, 0x00000005 },
  { SUB, 0x80ffffff, 0x81000004, 0x00000009 },
  { SUB, 0x81000000, 0x80ffffff, 0x80000001 },
  { SUB, 0x81000001, 0x80800001, 0x80800001 },
  { SUB, 0x81000001, 0x80ffffff, 0x80000003 },
  { SUB, 0x81000002, 0x80800001, 0x80800003 },
  { SUB, 0x817fffff, 0x81800000, 0x00000002 },
  { SUB, 0x81800000, 0x817fffff, 0x80000002 },
  { SUB, 0x81800001, 0x817fffff, 0x80000006 },
  { SUB, 0x81800002, 0x81000003, 0x81000001 },
  { SUB, 0xbf800000, 0x00000000, 0xbf800000 },
  { SUB, 0xbf800000, 0x3f800003, 0xc0000002 },
  { SUB, 0xbf800001, 0x3f800000, 0xc0000000 },
  { SUB, 0xbf800001, 0xbf800000, 0xb4000000 },
  { SUB, 0xbf800001, 0xbf800002, 0x34000000 },
  { SUB, 0xbffffffc, 0xbffffffd, 0x34000000 },
  { SUB, 0xbfffffff, 0x80000001, 0xbfffffff },
  { SUB, 0xbfffffff, 0xc0000000, 0x34000000 },
  { SUB, 0xc0000000, 0x40000001, 0xc0800000 },
  { SUB, 0xc0000000, 0xbfffffff, 0xb4000000 },
  { SUB, 0xc0000000, 0xc0000001, 0x34800000 },
  { SUB, 0xc0000001, 0x40000002, 0xc0800002 },
  { SUB, 0xc0000001, 0xbf800001, 0xbf800001 },
  { SUB, 0xc0000002, 0xbf800001, 0xbf800003 },
  { SUB, 0xc0000002, 0xbf800003, 0xbf800001 },
  { SUB, 0xc0000004, 0xc0000003, 0xb4800000 },
  { SUB, 0xc0400000, 0xc0400000, 0x00000000 },
  { SUB, 0xc07fffff, 0x33ffffff, 0xc07fffff },
  { SUB, 0xc07fffff, 0x34000000, 0xc0800000 },
  { SUB, 0xc07fffff, 0xc07ffffe, 0xb4800000 },
  { SUB, 0xc07fffff, 0xc0800002, 0x35a00000 },
  { SUB, 0xc0800001, 0xc07fffff, 0xb5400000 },
  { SUB, 0xfd800001, 0xfd7fffff, 0xf2400000 },
  { SUB, 0xfe7fffff, 0xfe7ffffe, 0xf2800000 },
  { SUB, 0xfe7fffff, 0xfe800002, 0x73a00000 },
  { SUB, 0xfe800000, 0xfe7fffff, 0xf2800000 },
  { SUB, 0xfe800000, 0xfe800001, 0x73000000 },
  { SUB, 0xfe800001, 0x7e800000, 0xff000000 },
  { SUB, 0xfe800001, 0xff000001, 0x7e800001 },
  { SUB, 0xfe800002, 0xfe000003, 0xfe000001 },
  { SUB, 0xfe800004, 0xfe800003, 0xf3000000 },
  { SUB, 0xfefffffe, 0x7efffffe, 0xff7ffffe },
  { SUB, 0xfefffffe, 0x7effffff, 0xff7ffffe },
  { SUB, 0xfefffffe, 0xfefffffe, 0x00000000 },
  { SUB, 0xfeffffff, 0x3f800000, 0xfeffffff },
  { SUB, 0xfeffffff, 0x7f000000, 0xff800000 },
  { SUB, 0xfeffffff, 0xbf800000, 0xfeffffff },
  { SUB, 0xfeffffff, 0xff000000, 0x73000000 },
  { SUB, 0xff000000, 0x00000000, 0xff000000 },
  { SUB, 0xff000000, 0x3f800000, 0xff000000 },
  { SUB, 0xff000000, 0x7f000000, 0xff800000 },
  { SUB, 0xff000000, 0x7f800000, 0xff800000 },
  { SUB, 0xff000000, 0x80000000, 0xff000000 },
  { SUB, 0xff000000, 0xbf800000, 0xff000000 },
  { SUB, 0xff000000, 0xff800000, 0x7f800000 },
  { SUB, 0xff000001, 0x7f000000, 0xff800000 },
  { SUB, 0xff000001, 0xff000000, 0xf3800000 },
  { SUB, 0xff000001, 0xff000002, 0x73800000 },
  { SUB, 0xff000002, 0xfe800001, 0xfe800003 },
  { SUB, 0xff7ffffe, 0x3f800000, 0xff7ffffe },
  { SUB, 0xff7ffffe, 0x7f7ffffe, 0xff800000 },
  { SUB, 0xff7ffffe, 0x7f7fffff, 0xff800000 },
  { SUB, 0xff7ffffe, 0xbf800000, 0xff7ffffe },
  { SUB, 0xff7ffffe, 0xff7fffff, 0x73800000 },
  { SUB, 0xff7fffff, 0x3f800000, 0xff7fffff },
  { SUB, 0xff7fffff, 0x80000001, 0xff7fffff },
  { SUB, 0xff7fffff, 0xbf800000, 0xff7fffff },
  { SUB, 0xff800000, 0x00000000, 0xff800000 },
  { SUB, 0xff800000, 0x007fffff, 0xff800000 },
  { SUB, 0xff800000, 0x7f000000, 0xff800000 },
  { SUB, 0xff800000, 0x7f800000, 0xff800000 },
  { SUB, 0xff800000, 0x80000000, 0xff800000 },
  { SUB, 0xff800000, 0x807fffff, 0xff800000 },
  { SUB, 0xff800000, 0xff000000, 0xff800000 },
  { SUB, 0x46f99cee, 0x4656466d, 0x468e79b8 },
  { SUB, 0x007ffff7, 0x00f7ffff, 0x80780008 },
  { SUB, 0x80ffffbf, 0x80800000, 0x807fffbf },

  // Tests that do depend on Arm NaN policy
  { ADD, 0x00000000, 0x7fad4be3, 0x7fed4be3 },
  { ADD, 0x00000000, 0x7fdf48c7, 0x7fdf48c7 },
  { ADD, 0x00000001, 0x7f970eba, 0x7fd70eba },
  { ADD, 0x00000001, 0x7fc35716, 0x7fc35716 },
  { ADD, 0x007fffff, 0x7fbf52d6, 0x7fff52d6 },
  { ADD, 0x007fffff, 0x7fc7a2df, 0x7fc7a2df },
  { ADD, 0x3f800000, 0x7f987a85, 0x7fd87a85 },
  { ADD, 0x3f800000, 0x7fc50124, 0x7fc50124 },
  { ADD, 0x7f7fffff, 0x7f95fd6f, 0x7fd5fd6f },
  { ADD, 0x7f7fffff, 0x7ffc28dc, 0x7ffc28dc },
  { ADD, 0x7f800000, 0x7f8dd790, 0x7fcdd790 },
  { ADD, 0x7f800000, 0x7fd2ef2b, 0x7fd2ef2b },
  { ADD, 0x7f800000, 0xff800000, 0x7fc00000 },
  { ADD, 0x7f99b09d, 0x00000000, 0x7fd9b09d },
  { ADD, 0x7f93541e, 0x00000001, 0x7fd3541e },
  { ADD, 0x7f9fc002, 0x007fffff, 0x7fdfc002 },
  { ADD, 0x7fb5db77, 0x3f800000, 0x7ff5db77 },
  { ADD, 0x7f9f5d92, 0x7f7fffff, 0x7fdf5d92 },
  { ADD, 0x7fac7a36, 0x7f800000, 0x7fec7a36 },
  { ADD, 0x7fb42008, 0x7fb0ee07, 0x7ff42008 },
  { ADD, 0x7f8bd740, 0x7fc7aaf1, 0x7fcbd740 },
  { ADD, 0x7f9bb57b, 0x80000000, 0x7fdbb57b },
  { ADD, 0x7f951a78, 0x80000001, 0x7fd51a78 },
  { ADD, 0x7f9ba63b, 0x807fffff, 0x7fdba63b },
  { ADD, 0x7f89463c, 0xbf800000, 0x7fc9463c },
  { ADD, 0x7fb63563, 0xff7fffff, 0x7ff63563 },
  { ADD, 0x7f90886e, 0xff800000, 0x7fd0886e },
  { ADD, 0x7fe8c15e, 0x00000000, 0x7fe8c15e },
  { ADD, 0x7fe915ae, 0x00000001, 0x7fe915ae },
  { ADD, 0x7ffa9b42, 0x007fffff, 0x7ffa9b42 },
  { ADD, 0x7fdad0f5, 0x3f800000, 0x7fdad0f5 },
  { ADD, 0x7fd10dcb, 0x7f7fffff, 0x7fd10dcb },
  { ADD, 0x7fd08e8a, 0x7f800000, 0x7fd08e8a },
  { ADD, 0x7fc3a9e6, 0x7f91a816, 0x7fd1a816 },
  { ADD, 0x7fdb229c, 0x7fc26c68, 0x7fdb229c },
  { ADD, 0x7fc9f6bb, 0x80000000, 0x7fc9f6bb },
  { ADD, 0x7ffa178b, 0x80000001, 0x7ffa178b },
  { ADD, 0x7fef2a0b, 0x807fffff, 0x7fef2a0b },
  { ADD, 0x7ffc885b, 0xbf800000, 0x7ffc885b },
  { ADD, 0x7fd26e8c, 0xff7fffff, 0x7fd26e8c },
  { ADD, 0x7fc55329, 0xff800000, 0x7fc55329 },
  { ADD, 0x80000000, 0x7fa833ae, 0x7fe833ae },
  { ADD, 0x80000000, 0x7fc4df63, 0x7fc4df63 },
  { ADD, 0x80000001, 0x7f98827d, 0x7fd8827d },
  { ADD, 0x80000001, 0x7fd7acc5, 0x7fd7acc5 },
  { ADD, 0x807fffff, 0x7fad19c0, 0x7fed19c0 },
  { ADD, 0x807fffff, 0x7ffe1907, 0x7ffe1907 },
  { ADD, 0xbf800000, 0x7fa95487, 0x7fe95487 },
  { ADD, 0xbf800000, 0x7fd2bbee, 0x7fd2bbee },
  { ADD, 0xff7fffff, 0x7f86ba21, 0x7fc6ba21 },
  { ADD, 0xff7fffff, 0x7feb00d7, 0x7feb00d7 },
  { ADD, 0xff800000, 0x7f800000, 0x7fc00000 },
  { ADD, 0xff800000, 0x7f857fdc, 0x7fc57fdc },
  { ADD, 0xff800000, 0x7fde0397, 0x7fde0397 },
  { SUB, 0x00000000, 0x7fad4be3, 0x7fed4be3 },
  { SUB, 0x00000000, 0x7fdf48c7, 0x7fdf48c7 },
  { SUB, 0x00000001, 0x7f970eba, 0x7fd70eba },
  { SUB, 0x00000001, 0x7fc35716, 0x7fc35716 },
  { SUB, 0x007fffff, 0x7fbf52d6, 0x7fff52d6 },
  { SUB, 0x007fffff, 0x7fc7a2df, 0x7fc7a2df },
  { SUB, 0x3f800000, 0x7f987a85, 0x7fd87a85 },
  { SUB, 0x3f800000, 0x7fc50124, 0x7fc50124 },
  { SUB, 0x7f7fffff, 0x7f95fd6f, 0x7fd5fd6f },
  { SUB, 0x7f7fffff, 0x7ffc28dc, 0x7ffc28dc },
  { SUB, 0x7f800000, 0x7f800000, 0x7fc00000 },
  { SUB, 0x7f800000, 0x7f8dd790, 0x7fcdd790 },
  { SUB, 0x7f800000, 0x7fd2ef2b, 0x7fd2ef2b },
  { SUB, 0x7f99b09d, 0x00000000, 0x7fd9b09d },
  { SUB, 0x7f93541e, 0x00000001, 0x7fd3541e },
  { SUB, 0x7f9fc002, 0x007fffff, 0x7fdfc002 },
  { SUB, 0x7fb5db77, 0x3f800000, 0x7ff5db77 },
  { SUB, 0x7f9f5d92, 0x7f7fffff, 0x7fdf5d92 },
  { SUB, 0x7fac7a36, 0x7f800000, 0x7fec7a36 },
  { SUB, 0x7fb42008, 0x7fb0ee07, 0x7ff42008 },
  { SUB, 0x7f8bd740, 0x7fc7aaf1, 0x7fcbd740 },
  { SUB, 0x7f9bb57b, 0x80000000, 0x7fdbb57b },
  { SUB, 0x7f951a78, 0x80000001, 0x7fd51a78 },
  { SUB, 0x7f9ba63b, 0x807fffff, 0x7fdba63b },
  { SUB, 0x7f89463c, 0xbf800000, 0x7fc9463c },
  { SUB, 0x7fb63563, 0xff7fffff, 0x7ff63563 },
  { SUB, 0x7f90886e, 0xff800000, 0x7fd0886e },
  { SUB, 0x7fe8c15e, 0x00000000, 0x7fe8c15e },
  { SUB, 0x7fe915ae, 0x00000001, 0x7fe915ae },
  { SUB, 0x7ffa9b42, 0x007fffff, 0x7ffa9b42 },
  { SUB, 0x7fdad0f5, 0x3f800000, 0x7fdad0f5 },
  { SUB, 0x7fd10dcb, 0x7f7fffff, 0x7fd10dcb },
  { SUB, 0x7fd08e8a, 0x7f800000, 0x7fd08e8a },
  { SUB, 0x7fc3a9e6, 0x7f91a816, 0x7fd1a816 },
  { SUB, 0x7fdb229c, 0x7fc26c68, 0x7fdb229c },
  { SUB, 0x7fc9f6bb, 0x80000000, 0x7fc9f6bb },
  { SUB, 0x7ffa178b, 0x80000001, 0x7ffa178b },
  { SUB, 0x7fef2a0b, 0x807fffff, 0x7fef2a0b },
  { SUB, 0x7ffc885b, 0xbf800000, 0x7ffc885b },
  { SUB, 0x7fd26e8c, 0xff7fffff, 0x7fd26e8c },
  { SUB, 0x7fc55329, 0xff800000, 0x7fc55329 },
  { SUB, 0x80000000, 0x7fa833ae, 0x7fe833ae },
  { SUB, 0x80000000, 0x7fc4df63, 0x7fc4df63 },
  { SUB, 0x80000001, 0x7f98827d, 0x7fd8827d },
  { SUB, 0x80000001, 0x7fd7acc5, 0x7fd7acc5 },
  { SUB, 0x807fffff, 0x7fad19c0, 0x7fed19c0 },
  { SUB, 0x807fffff, 0x7ffe1907, 0x7ffe1907 },
  { SUB, 0xbf800000, 0x7fa95487, 0x7fe95487 },
  { SUB, 0xbf800000, 0x7fd2bbee, 0x7fd2bbee },
  { SUB, 0xff7fffff, 0x7f86ba21, 0x7fc6ba21 },
  { SUB, 0xff7fffff, 0x7feb00d7, 0x7feb00d7 },
  { SUB, 0xff800000, 0x7f857fdc, 0x7fc57fdc },
  { SUB, 0xff800000, 0x7fde0397, 0x7fde0397 },
  { SUB, 0xff800000, 0xff800000, 0x7fc00000 },
};

float
make_float (uint32_t x)
{
  float r;
  memcpy (&r, &x, sizeof (r));
  return r;
}

uint32_t
unmake_float (float x)
{
  uint32_t r;
  memcpy (&r, &x, sizeof (r));
  return r;
}

int
main (void)
{
  bool failed = false;

  for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
    {
      const struct test *t = &tests[i];

#ifdef USE_NATIVE_ARITHMETIC
      /* If you compile with USE_NATIVE_ARITHMETIC defined, the same
       * set of tests will be run using the toolchain's built in float
       * arithmetic, instead of calling arm_fp_fadd and arm_fp_fsub. */
      float in1 = make_float (t->in1);
      float in2 = make_float (t->in2);
      float out = (t->op == ADD ? in1 + in2 : in1 - in2);;
      uint32_t outbits = unmake_float (out);
#else
      extern uint32_t arm_fp_fadd(uint32_t, uint32_t);
      extern uint32_t arm_fp_fsub(uint32_t, uint32_t);
      uint32_t outbits = (t->op == ADD ? arm_fp_fadd(t->in1, t->in2) :
                          arm_fp_fsub(t->in1, t->in2));
#endif

      if (outbits != t->out)
	{
	  printf ("FAIL: %s(%08" PRIx32 ", %08" PRIx32 ") -> %08" PRIx32
		  ", expected %08" PRIx32 "\n",
                  (t->op == ADD ? "fadd" : "fsub"),
		  t->in1, t->in2, outbits, t->out);
	  failed = true;
	}
    }

  if (!failed)
    printf ("all passed\n");

  return failed;
}
